package day11.HomeWork;

import java.util.concurrent.locks.ReentrantLock;

//b.通过Lock锁编写三个线程 让其出现死锁的案例,
// 提示: 添加3个对象  每个线程 分别锁两个对象 让其构成一个循环链  相互等待  可以参考课上的案例
public class DeadLock {
    ReentrantLock lock1 = new ReentrantLock();
    ReentrantLock lock2 = new ReentrantLock();
    ReentrantLock lock3 = new ReentrantLock();

    public void test1() {   //1 2
        String name = Thread.currentThread().getName();
        lock1.lock();
        System.out.println(name + "获取了lock1的锁,等待获取lock2的锁");
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        lock2.lock();
        System.out.println(name + "获取了lock1和lock2的锁");
        lock2.unlock();
        System.out.println(name + "释放了lock2的锁");
        lock1.unlock();
        System.out.println(name + "释放了lock2和lock1的锁");
    }

    public void test2() {   //3 1
        String name = Thread.currentThread().getName();
        lock3.lock();
        System.out.println(name + "获取了lock3的锁,等待获取lock1的锁");
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        lock1.lock();
        System.out.println(name + "获取了lock1和lock3的锁");
        lock1.unlock();
        System.out.println(name + "释放了lock1的锁");
        lock3.unlock();
        System.out.println(name + "释放了lock1和lock3的锁");
    }

    public void test3() {   //2 3
        String name = Thread.currentThread().getName();
        lock2.lock();
        System.out.println(name + "获取了lock2的锁,等待获取lock3的锁");
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        lock3.lock();
        System.out.println(name + "获取了lock2和lock3的锁");
        lock3.unlock();
        System.out.println(name + "释放了lock3的锁");
        lock2.unlock();
        System.out.println(name + "释放了lock2和lock3的锁");
    }

    public static void main(String[] args) {
        DeadLock dl = new DeadLock();
        new Thread(() -> {
            dl.test1();
        }, "线程1").start();
        new Thread(() -> {
            dl.test2();
        }, "线程2").start();
        new Thread(() -> {
            dl.test3();
        }, "线程3").start();

    }

}
